package com.yuanren.em.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yuanren.em.entity.*;
import com.yuanren.em.mapper.*;
import com.yuanren.em.utils.TokenUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.HashMap;

@Service
public class MemberService extends ServiceImpl<MemberLevelMapper, MemberLevel> {
    
    @Resource
    private MemberLevelMapper memberLevelMapper;
    
    @Resource
    private MemberPointsMapper memberPointsMapper;
    
    @Resource
    private UserMapper userMapper;
    
    @Resource
    private MemberBenefitUsageMapper memberBenefitUsageMapper;
    
    @Resource
    private MemberNotificationMapper memberNotificationMapper;
    
    @Resource
    private PointsExchangeProductMapper pointsExchangeProductMapper;
    
    @Resource
    private PointsExchangeRecordMapper pointsExchangeRecordMapper;
    
    @Resource
    private MemberCouponMapper memberCouponMapper;

    // ==================== 会员等级管理 ====================
    
    /**
     * 分页获取会员等级列表
     */
    public IPage<MemberLevel> getLevelPage(int pageNum, int pageSize, String levelName, String levelCode) {
        IPage<MemberLevel> page = new Page<>(pageNum, pageSize);
        return memberLevelMapper.selectLevelPageWithUserCount(page, levelName, levelCode);
    }
    
    /**
     * 获取所有启用的等级
     */
    public List<MemberLevel> getActiveLevels() {
        return memberLevelMapper.selectActiveLevels();
    }
    
    /**
     * 根据积分获取对应等级
     */
    public MemberLevel getLevelByPoints(Integer points) {
        return memberLevelMapper.selectLevelByPoints(points);
    }
    
    /**
     * 创建或更新会员等级
     */
    @Transactional
    public void saveOrUpdateLevel(MemberLevel level) {
        if (level.getId() == null) {
            level.setCreateTime(new Date());
        }
        level.setUpdateTime(new Date());
        saveOrUpdate(level);
    }
    
    /**
     * 删除会员等级
     */
    @Transactional
    public void deleteLevel(Long levelId) {
        // 检查是否有用户使用该等级
        // 这里简化处理，实际应该检查用户关联
        removeById(levelId);
    }
    
    // ==================== 会员积分管理 ====================
    
    /**
     * 分页获取积分记录
     */
    public IPage<MemberPoints> getPointsPage(int pageNum, int pageSize, Long userId, String changeType, String userName) {
        IPage<MemberPoints> page = new Page<>(pageNum, pageSize);
        return memberPointsMapper.selectPointsPageWithUser(page, userId, changeType, userName);
    }
    
    /**
     * 获取用户积分记录
     */
    public List<MemberPoints> getUserPointsHistory(Long userId) {
        return memberPointsMapper.selectByUserId(userId);
    }
    
    /**
     * 获取用户当前可用积分
     */
    public Integer getUserAvailablePoints(Long userId) {
        return memberPointsMapper.getUserAvailablePoints(userId);
    }
    
    /**
     * 添加积分
     */
    @Transactional
    public void addPoints(Long userId, Integer points, String changeType, Long relatedId, String description) {
        // 获取当前积分余额
        Integer currentBalance = getUserAvailablePoints(userId);
        Integer newBalance = currentBalance + points;
        
        // 创建积分记录
        MemberPoints pointsRecord = new MemberPoints();
        pointsRecord.setUserId(userId);
        pointsRecord.setPointsChange(points);
        pointsRecord.setPointsBalance(newBalance);
        pointsRecord.setChangeType(changeType);
        pointsRecord.setRelatedId(relatedId);
        pointsRecord.setDescription(description);
        pointsRecord.setCreateTime(new Date());
        pointsRecord.setIsExpired(false);
        
        memberPointsMapper.insert(pointsRecord);
        
        // 检查是否需要升级等级
        checkAndUpgradeLevel(userId, newBalance);
        
        // 发送积分获得通知
        sendPointsNotification(userId, points, "POINTS_EARNED", description);
    }
    
    /**
     * 扣除积分
     */
    @Transactional
    public boolean deductPoints(Long userId, Integer points, String changeType, Long relatedId, String description) {
        // 检查积分是否足够
        Integer currentBalance = getUserAvailablePoints(userId);
        if (currentBalance < points) {
            return false; // 积分不足
        }
        
        Integer newBalance = currentBalance - points;
        
        // 创建积分记录
        MemberPoints pointsRecord = new MemberPoints();
        pointsRecord.setUserId(userId);
        pointsRecord.setPointsChange(-points);
        pointsRecord.setPointsBalance(newBalance);
        pointsRecord.setChangeType(changeType);
        pointsRecord.setRelatedId(relatedId);
        pointsRecord.setDescription(description);
        pointsRecord.setCreateTime(new Date());
        pointsRecord.setIsExpired(false);
        
        memberPointsMapper.insert(pointsRecord);
        return true;
    }
    
    /**
     * 管理员调整积分
     */
    @Transactional
    public void adjustPoints(Long userId, Integer points, String description) {
        String changeType = points > 0 ? "ADMIN_ADD" : "ADMIN_DEDUCT";
        if (points > 0) {
            addPoints(userId, points, changeType, null, description);
        } else {
            // 对于扣除积分，需要检查余额
            Integer currentBalance = getUserAvailablePoints(userId);
            Integer newBalance = currentBalance + points; // points是负数
            
            MemberPoints pointsRecord = new MemberPoints();
            pointsRecord.setUserId(userId);
            pointsRecord.setPointsChange(points);
            pointsRecord.setPointsBalance(Math.max(0, newBalance)); // 确保不为负数
            pointsRecord.setChangeType(changeType);
            pointsRecord.setDescription(description);
            pointsRecord.setCreateTime(new Date());
            pointsRecord.setIsExpired(false);
            
            memberPointsMapper.insert(pointsRecord);
        }
    }
    
    // ==================== 会员等级升级 ====================
    
    /**
     * 检查并升级用户等级
     */
    @Transactional
    public void checkAndUpgradeLevel(Long userId, Integer totalPoints) {
        // 根据积分获取应该的等级
        MemberLevel targetLevel = getLevelByPoints(totalPoints);
        if (targetLevel == null) {
            return;
        }
        
        // 这里简化处理，实际应该检查用户当前等级并进行升级
        // 可以发送升级通知等
        sendLevelUpNotification(userId, null, targetLevel);
    }
    
    // ==================== 会员权益使用记录 ====================
    
    /**
     * 分页获取权益使用记录
     */
    public IPage<MemberBenefitUsage> getBenefitUsagePage(int pageNum, int pageSize, Long userId, String usageType, String status) {
        Page<MemberBenefitUsage> page = new Page<>(pageNum, pageSize);
        return memberBenefitUsageMapper.selectUsagePageWithInfo(page, userId, usageType, status);
    }
    
    /**
     * 记录权益使用
     */
    @Transactional
    public void recordBenefitUsage(Long userId, Long benefitId, String usageType, Long orderId, 
                                   BigDecimal discountAmount, BigDecimal originalAmount, 
                                   BigDecimal finalAmount, String description) {
        MemberBenefitUsage usage = new MemberBenefitUsage();
        usage.setUserId(userId);
        usage.setBenefitId(benefitId);
        usage.setUsageType(usageType);
        usage.setOrderId(orderId);
        usage.setDiscountAmount(discountAmount);
        usage.setOriginalAmount(originalAmount);
        usage.setFinalAmount(finalAmount);
        usage.setUsageDate(LocalDateTime.now());
        usage.setDescription(description);
        usage.setStatus("ACTIVE");
        usage.setCreatedAt(LocalDateTime.now());
        usage.setUpdatedAt(LocalDateTime.now());
        
        memberBenefitUsageMapper.insert(usage);
    }
    
    /**
     * 获取用户权益使用记录
     */
    public List<MemberBenefitUsage> getUserBenefitUsage(Long userId, Integer limit) {
        return memberBenefitUsageMapper.selectByUserId(userId, limit);
    }
    
    /**
     * 获取权益使用统计
     */
    public Map<String, Object> getBenefitUsageStats() {
        return memberBenefitUsageMapper.selectUsageStats();
    }
    
    // ==================== 会员通知管理 ====================
    
    /**
     * 分页获取会员通知
     */
    public IPage<MemberNotification> getNotificationPage(int pageNum, int pageSize, Long userId, String notificationType, Boolean isRead) {
        Page<MemberNotification> page = new Page<>(pageNum, pageSize);
        QueryWrapper<MemberNotification> wrapper = new QueryWrapper<>();
        
        if (notificationType != null && !notificationType.isEmpty()) {
            wrapper.eq("notification_type", notificationType);
        }
        if (isRead != null) {
            wrapper.eq("is_read", isRead);
        }
        
        wrapper.orderByDesc("created_at");
        return memberNotificationMapper.selectPage(page, wrapper);
    }
    
    /**
     * 获取用户未读通知
     */
    public List<MemberNotification> getUserUnreadNotifications(Long userId, Integer limit) {
        return memberNotificationMapper.selectUnreadByUserId(userId, limit);
    }
    
    /**
     * 获取用户未读通知数量
     */
    public Integer getUserUnreadNotificationCount(Long userId) {
        return memberNotificationMapper.countUnreadByUserId(userId);
    }

    /**
     * 获取用户通知分页列表
     */
    public IPage<MemberNotification> getUserNotificationPage(int pageNum, int pageSize, Long userId, String notificationType, Boolean isRead) {
        Page<MemberNotification> page = new Page<>(pageNum, pageSize);
        QueryWrapper<MemberNotification> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId);
        
        if (notificationType != null && !notificationType.isEmpty()) {
            wrapper.eq("notification_type", notificationType);
        }
        if (isRead != null) {
            wrapper.eq("is_read", isRead);
        }
        
        wrapper.orderByDesc("created_at");
        return memberNotificationMapper.selectPage(page, wrapper);
    }
    
    /**
     * 获取会员通知统计
     */
    public Map<String, Object> getNotificationStats() {
        Map<String, Object> stats = new HashMap<>();
        
        // 总通知数
        Long totalNotifications = memberNotificationMapper.selectCount(null);
        
        // 已读通知数
        QueryWrapper<MemberNotification> readWrapper = new QueryWrapper<>();
        readWrapper.eq("is_read", true);
        Long readNotifications = memberNotificationMapper.selectCount(readWrapper);
        
        // 未读通知数
        Long unreadNotifications = totalNotifications - readNotifications;
        
        // 阅读率
        double readRate = totalNotifications > 0 ? (readNotifications * 100.0 / totalNotifications) : 0;
        
        stats.put("totalNotifications", totalNotifications);
        stats.put("readNotifications", readNotifications);
        stats.put("unreadNotifications", unreadNotifications);
        stats.put("readRate", Math.round(readRate * 100.0) / 100.0);
        
        return stats;
    }
    
    /**
     * 标记通知为已读
     */
    @Transactional
    public void markNotificationsAsRead(Long userId, List<Long> notificationIds) {
        String ids = String.join(",", notificationIds.stream().map(String::valueOf).toArray(String[]::new));
        memberNotificationMapper.markAsRead(userId, ids);
    }
    
    /**
     * 标记所有通知为已读
     */
    @Transactional
    public void markAllNotificationsAsRead(Long userId) {
        memberNotificationMapper.markAllAsReadByUserId(userId);
    }
    
    /**
     * 获取所有用户ID
     */
    public List<Long> getAllUserIds() {
        return userMapper.selectAllUserIds();
    }
    
    /**
     * 根据等级获取用户ID列表
     */
    public List<Long> getUserIdsByLevels(List<Long> levelIds) {
        return userMapper.selectUserIdsByLevels(levelIds);
    }
    
    /**
     * 批量发送通知
     */
    @Transactional
    public void batchSendNotification(List<Long> userIds, String notificationType, String title, String content) {
        for (Long userId : userIds) {
            MemberNotification notification = new MemberNotification();
            notification.setUserId(userId);
            notification.setNotificationType(notificationType);
            notification.setTitle(title);
            notification.setContent(content);
            notification.setIsRead(false);
            notification.setCreatedAt(LocalDateTime.now());
            notification.setUpdatedAt(LocalDateTime.now());
            
            memberNotificationMapper.insert(notification);
        }
    }
    
    /**
     * 删除通知
     */
    @Transactional
    public void deleteNotification(Long id) {
        memberNotificationMapper.deleteById(id);
    }
    
    /**
     * 批量删除通知
     */
    @Transactional
    public void batchDeleteNotifications(List<Long> notificationIds) {
        memberNotificationMapper.deleteBatchIds(notificationIds);
    }
    
    /**
     * 发送等级升级通知
     */
    @Transactional
    public void sendLevelUpNotification(Long userId, MemberLevel fromLevel, MemberLevel toLevel) {
        MemberNotification notification = new MemberNotification();
        notification.setUserId(userId);
        notification.setNotificationType("LEVEL_UP");
        notification.setTitle("恭喜您，会员等级升级了！");
        notification.setContent(String.format("您的会员等级已从 %s 升级为 %s，享受更多专属权益！", 
                fromLevel != null ? fromLevel.getLevelName() : "普通会员", toLevel.getLevelName()));
        notification.setFromLevelId(fromLevel != null ? fromLevel.getId() : null);
        notification.setToLevelId(toLevel.getId());
        notification.setIsRead(false);
        notification.setCreatedAt(LocalDateTime.now());
        notification.setUpdatedAt(LocalDateTime.now());
        
        memberNotificationMapper.insert(notification);
    }
    
    /**
     * 发送积分获得通知
     */
    @Transactional
    public void sendPointsNotification(Long userId, Integer points, String notificationType, String description) {
        MemberNotification notification = new MemberNotification();
        notification.setUserId(userId);
        notification.setNotificationType(notificationType);
        notification.setTitle("积分获得通知");
        notification.setContent(String.format("您获得了 %d 积分！%s", points, description));
        notification.setPointsAmount(points);
        notification.setIsRead(false);
        notification.setCreatedAt(LocalDateTime.now());
        notification.setUpdatedAt(LocalDateTime.now());
        
        memberNotificationMapper.insert(notification);
    }
    
    // ==================== 积分兑换商城 ====================
    
    /**
     * 分页获取积分兑换商品（前台）
     */
    public IPage<PointsExchangeProduct> getExchangeProductsPage(int pageNum, int pageSize, String category, 
                                                                String productType, String name) {
        Page<PointsExchangeProduct> page = new Page<>(pageNum, pageSize);
        QueryWrapper<PointsExchangeProduct> wrapper = new QueryWrapper<>();
        
        // 前台只显示激活的商品
        wrapper.eq("is_active", true);
        
        if (category != null && !category.isEmpty()) {
            wrapper.eq("category", category);
        }
        if (productType != null && !productType.isEmpty()) {
            wrapper.eq("product_type", productType);
        }
        if (name != null && !name.isEmpty()) {
            wrapper.like("name", name);
        }
        
        wrapper.orderByAsc("sort_order").orderByAsc("points_required");
        return pointsExchangeProductMapper.selectPage(page, wrapper);
    }
    
    /**
     * 分页获取积分兑换商品（后台管理）
     */
    public IPage<PointsExchangeProduct> getExchangeProductsPageForAdmin(int pageNum, int pageSize, String category, 
                                                                        String productType, Boolean isActive, String name) {
        Page<PointsExchangeProduct> page = new Page<>(pageNum, pageSize);
        QueryWrapper<PointsExchangeProduct> wrapper = new QueryWrapper<>();
        
        if (category != null && !category.isEmpty()) {
            wrapper.eq("category", category);
        }
        if (productType != null && !productType.isEmpty()) {
            wrapper.eq("product_type", productType);
        }
        if (isActive != null) {
            wrapper.eq("is_active", isActive);
        }
        if (name != null && !name.isEmpty()) {
            wrapper.like("name", name);
        }
        
        wrapper.orderByAsc("sort_order").orderByDesc("created_at");
        return pointsExchangeProductMapper.selectPage(page, wrapper);
    }
    
    /**
     * 根据ID获取积分兑换商品
     */
    public PointsExchangeProduct getExchangeProductById(Long id) {
        return pointsExchangeProductMapper.selectById(id);
    }
    
    /**
     * 创建积分兑换商品
     */
    @Transactional
    public void createExchangeProduct(PointsExchangeProduct product) {
        product.setCreatedAt(LocalDateTime.now());
        product.setUpdatedAt(LocalDateTime.now());
        pointsExchangeProductMapper.insert(product);
    }
    
    /**
     * 更新积分兑换商品
     */
    @Transactional
    public void updateExchangeProduct(PointsExchangeProduct product) {
        product.setUpdatedAt(LocalDateTime.now());
        pointsExchangeProductMapper.updateById(product);
    }
    
    /**
     * 删除积分兑换商品
     */
    @Transactional
    public void deleteExchangeProduct(Long id) {
        pointsExchangeProductMapper.deleteById(id);
    }
    
    /**
     * 调整商品库存
     */
    @Transactional
    public void adjustProductStock(Long productId, Integer adjustAmount, String reason) {
        PointsExchangeProduct product = pointsExchangeProductMapper.selectById(productId);
        if (product == null) {
            throw new RuntimeException("商品不存在");
        }
        
        int newStock = product.getStockQuantity() + adjustAmount;
        if (newStock < 0) {
            throw new RuntimeException("库存不足，无法调整");
        }
        
        product.setStockQuantity(newStock);
        product.setUpdatedAt(LocalDateTime.now());
        pointsExchangeProductMapper.updateById(product);
    }
    
    /**
     * 获取热门兑换商品
     */
    public List<PointsExchangeProduct> getHotExchangeProducts(Integer limit) {
        QueryWrapper<PointsExchangeProduct> wrapper = new QueryWrapper<>();
        wrapper.eq("is_active", true);
        wrapper.orderByAsc("sort_order").orderByAsc("points_required");
        wrapper.last("LIMIT " + limit);
        return pointsExchangeProductMapper.selectList(wrapper);
    }
    
    /**
     * 获取积分兑换商品统计
     */
    public Map<String, Object> getExchangeProductStats() {
        Map<String, Object> stats = new HashMap<>();
        
        // 总商品数
        Long totalProducts = pointsExchangeProductMapper.selectCount(null);
        
        // 上架商品数
        QueryWrapper<PointsExchangeProduct> activeWrapper = new QueryWrapper<>();
        activeWrapper.eq("is_active", true);
        Long activeProducts = pointsExchangeProductMapper.selectCount(activeWrapper);
        
        // 有库存商品数
        QueryWrapper<PointsExchangeProduct> stockWrapper = new QueryWrapper<>();
        stockWrapper.gt("stock_quantity", 0);
        Long inStockProducts = pointsExchangeProductMapper.selectCount(stockWrapper);
        
        // 平均所需积分（简化处理）
        Double avgPointsRequired = 0.0;
        if (totalProducts > 0) {
            List<PointsExchangeProduct> products = pointsExchangeProductMapper.selectList(null);
            avgPointsRequired = products.stream()
                    .mapToInt(PointsExchangeProduct::getPointsRequired)
                    .average()
                    .orElse(0.0);
        }
        
        stats.put("totalProducts", totalProducts);
        stats.put("activeProducts", activeProducts);
        stats.put("inStockProducts", inStockProducts);
        stats.put("avgPointsRequired", Math.round(avgPointsRequired * 100.0) / 100.0);
        
        return stats;
    }
    
    /**
     * 积分兑换商品
     */
    @Transactional
    public String exchangeProduct(Long userId, Long productId, Integer quantity) {
        // 获取商品信息
        PointsExchangeProduct product = pointsExchangeProductMapper.selectById(productId);
        if (product == null || !product.getIsActive()) {
            throw new RuntimeException("商品不存在或已下架");
        }
        
        // 检查库存
        if (product.getStockQuantity() < quantity) {
            throw new RuntimeException("商品库存不足");
        }
        
        // 计算所需积分
        Integer totalPoints = product.getPointsRequired() * quantity;
        
        // 检查用户积分是否足够
        Integer userPoints = getUserAvailablePoints(userId);
        if (userPoints < totalPoints) {
            throw new RuntimeException("积分不足");
        }
        
        // 扣除积分
        boolean success = deductPoints(userId, totalPoints, "POINTS_EXCHANGE", productId, 
                "兑换商品：" + product.getName() + " x" + quantity);
        if (!success) {
            throw new RuntimeException("积分扣除失败");
        }
        
        // 减少库存
        int stockUpdated = pointsExchangeProductMapper.reduceStock(productId, quantity);
        if (stockUpdated == 0) {
            throw new RuntimeException("库存不足，兑换失败");
        }
        
        // 生成兑换码
        String exchangeCode = generateExchangeCode();
        
        // 创建兑换记录
        PointsExchangeRecord record = new PointsExchangeRecord();
        record.setUserId(userId);
        record.setProductId(productId);
        record.setPointsSpent(totalPoints);
        record.setQuantity(quantity);
        record.setExchangeCode(exchangeCode);
        record.setStatus("COMPLETED");
        record.setExchangeDate(LocalDateTime.now());
        
        // 设置过期时间（如果是优惠券类商品）
        if (product.getValidityDays() != null && product.getValidityDays() > 0) {
            record.setExpireDate(LocalDateTime.now().plusDays(product.getValidityDays()));
        }
        
        record.setCreatedAt(LocalDateTime.now());
        record.setUpdatedAt(LocalDateTime.now());
        
        pointsExchangeRecordMapper.insert(record);
        
        // 如果是优惠券类商品，创建优惠券
        if ("DISCOUNT_COUPON".equals(product.getProductType()) || "FREE_SHIPPING".equals(product.getProductType())) {
            createCouponFromExchange(userId, product, record);
        }
        
        return exchangeCode;
    }
    
    /**
     * 生成兑换码
     */
    private String generateExchangeCode() {
        return "EX" + System.currentTimeMillis() + UUID.randomUUID().toString().substring(0, 8).toUpperCase();
    }
    
    /**
     * 从兑换记录创建优惠券
     */
    @Transactional
    public void createCouponFromExchange(Long userId, PointsExchangeProduct product, PointsExchangeRecord record) {
        MemberCoupon coupon = new MemberCoupon();
        coupon.setUserId(userId);
        coupon.setCouponCode(generateCouponCode());
        coupon.setCouponName(product.getName());
        
        // 设置优惠券类型和金额
        if ("DISCOUNT_COUPON".equals(product.getProductType())) {
            if (product.getDiscountRate() != null) {
                coupon.setCouponType("DISCOUNT");
                coupon.setDiscountRate(product.getDiscountRate());
            } else {
                coupon.setCouponType("AMOUNT");
                coupon.setDiscountAmount(product.getOriginalPrice());
            }
        } else if ("FREE_SHIPPING".equals(product.getProductType())) {
            coupon.setCouponType("FREE_SHIPPING");
            coupon.setDiscountAmount(product.getOriginalPrice());
        }
        
        coupon.setMinOrderAmount(product.getMinOrderAmount());
        coupon.setMaxDiscountAmount(product.getMaxDiscountAmount());
        coupon.setSource("POINTS_EXCHANGE");
        coupon.setSourceId(record.getId());
        coupon.setExpireDate(record.getExpireDate());
        coupon.setIsUsed(false);
        coupon.setCreatedAt(LocalDateTime.now());
        coupon.setUpdatedAt(LocalDateTime.now());
        
        memberCouponMapper.insert(coupon);
    }
    
    /**
     * 生成优惠券码
     */
    private String generateCouponCode() {
        String code;
        do {
            code = "CP" + System.currentTimeMillis() + UUID.randomUUID().toString().substring(0, 6).toUpperCase();
        } while (memberCouponMapper.countByCouponCode(code) > 0);
        return code;
    }
    
    /**
     * 获取用户兑换记录
     */
    public List<PointsExchangeRecord> getUserExchangeRecords(Long userId, Integer limit) {
        QueryWrapper<PointsExchangeRecord> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId);
        wrapper.orderByDesc("exchange_date");
        wrapper.last("LIMIT " + limit);
        return pointsExchangeRecordMapper.selectList(wrapper);
    }
    
    /**
     * 分页获取兑换记录
     */
    public IPage<PointsExchangeRecord> getExchangeRecordPage(int pageNum, int pageSize, Long userId, 
                                                             Long productId, String status, String category) {
        Page<PointsExchangeRecord> page = new Page<>(pageNum, pageSize);
        QueryWrapper<PointsExchangeRecord> wrapper = new QueryWrapper<>();
        
        if (userId != null) {
            wrapper.eq("user_id", userId);
        }
        if (productId != null) {
            wrapper.eq("product_id", productId);
        }
        if (status != null && !status.isEmpty()) {
            wrapper.eq("status", status);
        }
        
        wrapper.orderByDesc("exchange_date");
        return pointsExchangeRecordMapper.selectPage(page, wrapper);
    }
    
    // ==================== 会员优惠券管理 ====================
    
    /**
     * 分页获取优惠券
     */
    public IPage<MemberCoupon> getCouponPage(int pageNum, int pageSize, Long userId, String couponType, 
                                             Boolean isUsed, String source) {
        Page<MemberCoupon> page = new Page<>(pageNum, pageSize);
        QueryWrapper<MemberCoupon> wrapper = new QueryWrapper<>();
        
        if (userId != null) {
            wrapper.eq("user_id", userId);
        }
        if (couponType != null && !couponType.isEmpty()) {
            wrapper.eq("coupon_type", couponType);
        }
        if (isUsed != null) {
            wrapper.eq("is_used", isUsed);
        }
        if (source != null && !source.isEmpty()) {
            wrapper.eq("source", source);
        }
        
        wrapper.orderByDesc("created_at");
        return memberCouponMapper.selectPage(page, wrapper);
    }
    
    /**
     * 获取用户可用优惠券
     */
    public List<MemberCoupon> getUserAvailableCoupons(Long userId) {
        QueryWrapper<MemberCoupon> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId);
        wrapper.eq("is_used", false);
        wrapper.gt("expire_date", LocalDateTime.now());
        wrapper.orderByAsc("expire_date");
        return memberCouponMapper.selectList(wrapper);
    }
    
    /**
     * 获取适用优惠券
     */
    public List<MemberCoupon> getApplicableCoupons(Long userId, BigDecimal orderAmount) {
        QueryWrapper<MemberCoupon> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId);
        wrapper.eq("is_used", false);
        wrapper.gt("expire_date", LocalDateTime.now());
        // 简化处理，只检查基本条件
        wrapper.orderByDesc("discount_amount");
        return memberCouponMapper.selectList(wrapper);
    }
    
    /**
     * 使用优惠券
     */
    @Transactional
    public MemberCoupon useCoupon(String couponCode, Long orderId) {
        QueryWrapper<MemberCoupon> wrapper = new QueryWrapper<>();
        wrapper.eq("coupon_code", couponCode);
        MemberCoupon coupon = memberCouponMapper.selectOne(wrapper);
        
        if (coupon == null) {
            throw new RuntimeException("优惠券不存在");
        }
        
        if (coupon.getIsUsed()) {
            throw new RuntimeException("优惠券已使用");
        }
        
        if (coupon.getExpireDate().isBefore(LocalDateTime.now())) {
            throw new RuntimeException("优惠券已过期");
        }
        
        // 标记为已使用
        coupon.setIsUsed(true);
        coupon.setUsedDate(LocalDateTime.now());
        coupon.setOrderId(orderId);
        coupon.setUpdatedAt(LocalDateTime.now());
        
        memberCouponMapper.updateById(coupon);
        
        return coupon;
    }
    
    /**
     * 计算优惠券折扣金额
     */
    public BigDecimal calculateCouponDiscount(MemberCoupon coupon, BigDecimal orderAmount) {
        if (coupon.getMinOrderAmount() != null && orderAmount.compareTo(coupon.getMinOrderAmount()) < 0) {
            return BigDecimal.ZERO;
        }
        
        BigDecimal discount = BigDecimal.ZERO;
        
        switch (coupon.getCouponType()) {
            case "AMOUNT":
                discount = coupon.getDiscountAmount();
                break;
            case "DISCOUNT":
                discount = orderAmount.multiply(coupon.getDiscountRate()).divide(BigDecimal.valueOf(100));
                if (coupon.getMaxDiscountAmount() != null && discount.compareTo(coupon.getMaxDiscountAmount()) > 0) {
                    discount = coupon.getMaxDiscountAmount();
                }
                break;
            case "FREE_SHIPPING":
                discount = coupon.getDiscountAmount(); // 免邮金额
                break;
        }
        
        return discount;
    }
    
    // ==================== 会员等级折扣 ====================
    
    /**
     * 计算会员等级折扣
     */
    public BigDecimal calculateMemberDiscount(Long userId, BigDecimal orderAmount) {
        Integer userPoints = getUserAvailablePoints(userId);
        MemberLevel level = getLevelByPoints(userPoints);
        
        if (level == null || level.getDiscountRate() == null) {
            return BigDecimal.ZERO;
        }
        
        BigDecimal discountRate = level.getDiscountRate().divide(BigDecimal.valueOf(100));
        BigDecimal discount = orderAmount.multiply(BigDecimal.ONE.subtract(discountRate));
        
        return orderAmount.subtract(discount);
    }
    
    /**
     * 应用会员等级折扣到订单
     */
    @Transactional
    public void applyMemberDiscountToOrder(Long userId, Long orderId, BigDecimal originalAmount, BigDecimal discountAmount) {
        Integer userPoints = getUserAvailablePoints(userId);
        MemberLevel level = getLevelByPoints(userPoints);
        
        if (level != null && discountAmount.compareTo(BigDecimal.ZERO) > 0) {
            // 记录权益使用
            recordBenefitUsage(userId, null, "DISCOUNT", orderId, discountAmount, originalAmount, 
                    originalAmount.subtract(discountAmount), 
                    "会员等级折扣：" + level.getLevelName() + " " + level.getDiscountRate() + "折");
        }
    }
    
    /**
     * 取消权益使用记录
     */
    @Transactional
    public void cancelBenefitUsage(Long id) {
        MemberBenefitUsage usage = memberBenefitUsageMapper.selectById(id);
        if (usage == null) {
            throw new RuntimeException("权益使用记录不存在");
        }
        
        if (!"ACTIVE".equals(usage.getStatus())) {
            throw new RuntimeException("权益使用记录状态不允许取消");
        }
        
        // 更新状态为已取消
        usage.setStatus("CANCELLED");
        usage.setUpdatedAt(LocalDateTime.now());
        memberBenefitUsageMapper.updateById(usage);
    }

    // ==================== 统计信息 ====================
    
    /**
     * 获取会员统计信息
     */
    public MemberStatistics getMemberStatistics() {
        MemberStatistics stats = new MemberStatistics();
        
        // 获取等级统计
        List<MemberLevel> levels = list();
        stats.setTotalLevels(levels.size());
        stats.setActiveLevels((int) levels.stream().filter(l -> l.getIsActive() != null && l.getIsActive()).count());
        
        // 获取积分统计
        MemberPointsMapper.PointsStatistics pointsStats = memberPointsMapper.getPointsStatistics();
        stats.setTotalPointsRecords(pointsStats.getTotalRecords());
        stats.setTotalPointsEarned(pointsStats.getTotalEarned());
        stats.setTotalPointsSpent(pointsStats.getTotalSpent());
        stats.setActiveUsers(pointsStats.getActiveUsers());
        
        return stats;
    }
    
    /**
     * 为订单添加积分
     */
    @Transactional
    public void addPointsForOrder(Long userId, Long orderId, BigDecimal orderAmount) {
        // 获取用户等级
        Integer userPoints = getUserAvailablePoints(userId);
        MemberLevel level = getLevelByPoints(userPoints);
        
        // 计算基础积分（1元=1积分）
        Integer basePoints = orderAmount.intValue();
        
        // 根据等级计算积分倍数
        BigDecimal multiplier = (level != null && level.getPointsRatio() != null) 
            ? level.getPointsRatio() 
            : BigDecimal.ONE;
        
        Integer finalPoints = BigDecimal.valueOf(basePoints).multiply(multiplier).intValue();
        
        addPoints(userId, finalPoints, "EARN_ORDER", orderId, 
                "订单消费获得积分，订单号：" + orderId + "，金额：" + orderAmount + "元");
    }
    
    /**
     * 为评论添加积分
     */
    @Transactional
    public void addPointsForComment(Long userId, Long commentId) {
        addPoints(userId, 10, "EARN_REVIEW", commentId, "发表商品评论获得积分奖励");
    }
    
    /**
     * 使用积分抵扣
     */
    @Transactional
    public boolean usePointsForDiscount(Long userId, Integer points, Long orderId) {
        return deductPoints(userId, points, "SPEND_DISCOUNT", orderId, "积分抵扣订单金额");
    }
    
    public static class MemberStatistics {
        private Integer totalLevels;
        private Integer activeLevels;
        private Integer totalPointsRecords;
        private Integer totalPointsEarned;
        private Integer totalPointsSpent;
        private Integer activeUsers;

        // Getters and Setters
        public Integer getTotalLevels() {
            return totalLevels;
        }

        public void setTotalLevels(Integer totalLevels) {
            this.totalLevels = totalLevels;
        }

        public Integer getActiveLevels() {
            return activeLevels;
        }

        public void setActiveLevels(Integer activeLevels) {
            this.activeLevels = activeLevels;
        }

        public Integer getTotalPointsRecords() {
            return totalPointsRecords;
        }

        public void setTotalPointsRecords(Integer totalPointsRecords) {
            this.totalPointsRecords = totalPointsRecords;
        }

        public Integer getTotalPointsEarned() {
            return totalPointsEarned;
        }

        public void setTotalPointsEarned(Integer totalPointsEarned) {
            this.totalPointsEarned = totalPointsEarned;
        }

        public Integer getTotalPointsSpent() {
            return totalPointsSpent;
        }

        public void setTotalPointsSpent(Integer totalPointsSpent) {
            this.totalPointsSpent = totalPointsSpent;
        }

        public Integer getActiveUsers() {
            return activeUsers;
        }

        public void setActiveUsers(Integer activeUsers) {
            this.activeUsers = activeUsers;
        }
    }
} 